﻿#region [ License information          ]
/* ************************************************************
 *
 * Copyright (c) Bjørn Bouet Smith, 2010, 2011
 *
 * This source code is subject to terms and conditions of 
 * Microsoft Public License (Ms-PL).
 * 
 * A copy of the license can be found in the license.txt
 * file at the root of this distribution. If you can not 
 * locate the License, please send an email to bjornsmith@gmail.com
 * 
 * By using this source code in any fashion, you are 
 * agreeing to be bound by the terms of the Microsoft 
 * Public License.
 *
 * You must not remove this notice, or any other, from this
 * software.
 *
 * ************************************************************/
#endregion

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using NUnit.Framework;
using Smith.AMC;
using Smith.AMC.Configuration;
using Smith.AMC.Network;

namespace MemcachedClientTests
{
    [TestFixture]
    public class MultiGetTest
    {

        private List<KeyValuePair<IPAddress, int>> servers = new List<KeyValuePair<IPAddress, int>>();
        private ServerNodeMonitorConfiguration config = new ServerNodeMonitorConfiguration();

        [TestFixtureSetUp]
        public void PerTestSetUp()
        {
            servers.Add(new KeyValuePair<IPAddress, int>(IPAddress.Parse("127.0.0.1"), 11211));
        }



        [Test]
        public void GetMultipleShouldReturnAll()
        {
            ServerPool pool = new ServerPool(servers, SocketType.Stream, ProtocolType.Tcp, 25, config);
            MemcachedClient client = new MemcachedClient(new SocketWorker(pool, TimeSpan.FromSeconds(20)));

            Dictionary<string, long> kv = new Dictionary<string, long>();
            kv.Add(Guid.NewGuid().ToString(), 10);
            kv.Add(Guid.NewGuid().ToString(), 15);
            
            foreach(string key in kv.Keys)
            {
                ICacheItem<long> cacheItem = new CacheItem<long>
                {
                    CacheKey = key,
                    LifeTime = TimeSpan.FromSeconds(0),
                    Value = kv[key]
                };
                IAsyncResult ar = client.BeginAdd(cacheItem, null, null);
                client.EndAdd<long>(ar);
            }


            IAsyncResult ar2 = client.BeginGetMultiple<long>(kv.Keys, null, null);
            ICollection<ICacheItem<long>> items = client.EndGetMultiple<long>(ar2);
            Assert.That(items.Count, Is.EqualTo(2));

            foreach(ICacheItem<long> item in items)
            {
                long expected = kv[item.CacheKey];
                Assert.That(item.Value, Is.EqualTo(expected));
                Console.WriteLine(expected);
            }
        }

        [Test]
        public void GetMultipleShouldReturnThoseThatAreAvailableEvenIfSomeDoesNotExist()
        {
            ServerPool pool = new ServerPool(servers, SocketType.Stream, ProtocolType.Tcp, 25, config);
            MemcachedClient client = new MemcachedClient(new SocketWorker(pool, TimeSpan.FromSeconds(20)));

            Dictionary<string, long> kv = new Dictionary<string, long>();
            string onlyExistingKey = Guid.NewGuid().ToString();
            kv.Add(onlyExistingKey, 10);
            kv.Add(Guid.NewGuid().ToString(), 15);

          
                ICacheItem<long> cacheItem = new CacheItem<long>
                {
                    CacheKey = onlyExistingKey,
                    LifeTime = TimeSpan.FromSeconds(0),
                    Value = kv[onlyExistingKey]
                };
                IAsyncResult ar = client.BeginAdd(cacheItem, null, null);
                client.EndAdd<long>(ar);
          


            IAsyncResult ar2 = client.BeginGetMultiple<long>(kv.Keys, null, null);
            ICollection<ICacheItem<long>> items = client.EndGetMultiple<long>(ar2);
            Assert.That(items.Count, Is.EqualTo(2));

            foreach (ICacheItem<long> item in items)
            {
                long expected = kv[item.CacheKey];
                if (item.CacheKey == onlyExistingKey)
                {
                    Assert.That(item.Value, Is.EqualTo(expected));
                }
                else
                {
                    // 0 is the default value of a long, so non existing values for a long should be 0
                    Assert.That(item.Value, Is.EqualTo(0));
                }
            }
        }
    }
}
